#include "stdafx.h"
#include <Strsafe.h>
#include "Device.h"
#include "HttpF2.h"

Device::Device(HDEVINFO devInfo,SP_DEVICE_INTERFACE_DATA *devData):
	UsbHid(devInfo,devData){
	accKey=0;
	offset=0;
	voltB=0;
	voltC=0;
	voltS=0;
}

Device::~Device(void){
}
UsbHid* Device::create(HDEVINFO devInfo,SP_DEVICE_INTERFACE_DATA *devData){
	return new Device(devInfo,devData);
}
void Device::sendReport(Report* buffer){
	if(buffer){
		UsbHid::sendReport(&buffer->report[3],sizeof(Report)-3);
		if(buffer->cmd==RPT_FIRMWARE)
			upgOrd=buffer->ord;
	}
}
void Device::single(ushort key,ushort val){
	switch(key){
	case RPT_STEPSLO:
		steps=(steps&0xffff0000)|val;
		break;
	case RPT_STEPSHI:
		steps=(steps&0xffff)|((uint)val<<16);
		break;
	case RPT_OFFSETLO:
		offset=(offset&0xffff0000)|val;
		break;
	case RPT_OFFSETHI:
		offset=(offset&0xffff)|((uint)val<<16);
		break;
	case RPT_TICKLO:
		tick=(tick&0xffff0000)|val;
		break;
	case RPT_TICKHI:
		tick=(tick&0xffff)|((uint)val<<16);
		break;
	case RPT_VERSION:
		version=val;
		upgrade.loadBin(serialNum,val);
		break;
	case RPT_VOLTS:
		voltS=val;
		break;
	case RPT_VOLTC:
		voltC=val;
		break;
	}
}
void Device::multiple(void){
	switch(report.cmd){
	case RPT_FIRMWARE:
		sendReport(upgrade.upgrade(&report));
		break;
	case RPT_DATAIMG:
		dataImg.set(&report);
		ushort* p=dataImg.get();
		if(p){
			HttpF2* h=0;
			try{
				h=new HttpF2(serialNum,version);
				h->put(L"/kalkr/",p,p[1]);
			}catch(int){
			}
			if(h)
				delete h;
		}
		break;
	}
}
uint Device::threadEntry(void){
	uint n=0;
	while(1){
		if(getReport(&report.report[3],sizeof(report)-3)){
			wchar_t x[1024];
			if(report.cmd&0x8000){
				multiple();
				StringCbPrintf(x,sizeof(x),_T("%x"),upgOrd);
			}else{
				ushort *e,*p=(ushort*)&report.cmd,i,v;
				for(e=p+32;p<e;){
					i=*p++;
					v=*p++;
					single(i,v);
				}
				uint t=localTick();
				if((t-n)>300){
					n=t;
					HttpF2* h=0;
					try{
						h=new HttpF2(serialNum,version);
						h->put(L"/kalkr/",&report.cmd,64);
					}catch(int){
					}
					if(h)
						delete h;
				}
				int a=tick+offset-t;
				if(a<0)
					a=-a;
				if(a>10){
					memset(&report,0,sizeof(report));
					report.cmd=RPT_TICKLO;
					report.ord=LOWORD(t);
					report.data[0]=RPT_TICKHI;
					report.data[1]=HIWORD(t);
					sendReport(&report);
				}else sendReport(upgrade.upgrade(0));
			}
		}
		else break;
	}
	return 0;
}